from classifier import Classifier

# A bloody large number.
INFINITY = 1.0e400

class NearestNeighbor2(Classifier):
    '''
    A very basic implementation of the nearest-neighbor learning algorithm.
    '''
    
    def classify(self, ins):
        '''
        Finds the closest example to the given instance (in terms of Euclidean distance), 
        and returns its class.
        
        @param instance: A tuple of numerical features.
        @return: The nearest neighbor's class.

        print 'welcome to classify ins is:'
        print ins
        exit()
        '''
        instance = ins[1]
        real_instance = ins[0]
        min_distance = INFINITY
        min_classification = None
        for example, classification in self.examples:
            '''print instance
            print 'example', example'''
            d = self._distance(instance, example[1])
            for cls in self.classes:
                for word_in_example in real_instance:
                        if word_in_example in self.parsed_classes.values():
                            return cls
            if d < min_distance:
                min_distance = d
                min_classification = classification
        return min_classification
    
    def learn(self, examples, classification_time_limit, learning_time_limit):
        '''
        Learns the classifier from the given examples.
        
        @param examples: A list of (instance, classification) tuples.
                         The instances are equal-lengthed tuples of features.
        @param classification_time_limit: The time limit for classification of a single instance.
        @param learning_time_limit: The time limit for learning.
        '''
        
        #getting the different classes and refining them
        self.classes = set()
        self.parsed_classes = {}
        for example in examples:
            self.classes.add(example[1])
        
        for cls in self.classes:
             self.parsed_classes[cls] = cls.replace('_','-').split('-')
        for cls1 in self.parsed_classes.values():
            for cls2 in self.parsed_classes.values():
                for word in cls1:
                    if word in cls2 and cls1 != cls2:
                        cls1.remove(word)
                        cls2.remove(word)
        
        self.examples = examples
    
    def _distance(self, x, y):
        if len(x) != len(y):
            raise IndexError
        return sum((x[i] - y[i])**2 for i in xrange(len(x)))
